using System;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using Kaz.HolidayManagementSystem.Business.Repositories;
using Kaz.HolidayManagementSystem.Business.Repositories.Interfaces;
using Kaz.HolidayManagementSystem.Common;
using Kaz.HolidayManagementSystem.Common.Enums;
using Kaz.HolidayManagementSystem.Common.Exceptions;

namespace Kaz.HolidayManagementSystem.Business.DomainObjects
{
    public class Employee
    {

        private IRepository _repository;

        public Employee(IRepository repository)
        {
            _repository = repository;
        }

        public Employee()
            : this(new SqlRepository())
        {

        }
        public string Id { get; set; }
       
        [Required(ErrorMessage = "Name cannot be empty.")]
        public string Name { get; set; }

        public DateTime DateOfBirth { get; set; }

        public DateTime JoiningDate { get; set; }

        public DesignationType Designation { get; set; }

        public string Address { get; set; }

        public string Mobile { get; set; }

        [Required(ErrorMessage = "Email address cannot be empty.")]
        [RegularExpression(Constants.EMAIL_REGEX, ErrorMessage="Invalid Email Address.")]
        public string Email { get; set; }

        public void Validate()
        {
            if (string.IsNullOrEmpty(Name))
                throw new RequiredFieldMissing("Name");

            if (JoiningDate <= DateTime.MinValue)
                throw new RequiredFieldMissing("JoiningDate");

            if (string.IsNullOrEmpty(Email))
                throw new RequiredFieldMissing("Email");

            Regex regex = new Regex(Constants.EMAIL_REGEX);
            if (!regex.IsMatch(Email))
                throw new InvalidField("Email");
            if (DateOfBirth > DateTime.Now)
                throw new ViolateConstraint("Date of birth should be less than today's date");

        }

        public bool Save()
        {
            Validate();
            return _repository.SaveEmployee(this);
        }
    }

    public class ViolateConstraint : Exception
    {
        public ViolateConstraint(string message)
            : base(message)
        {

        }
    }
}